package com.ccl.iot.views;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.os.Message;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;

public class MarqueeLabel extends View {
	private static float KDEFAULT_LABEL_SIZE = 0;
	private static float KMARQUEE_STEP_WIDTH = 1;
	
	private static int KMESSAGE_REFRESH_LABEL = 1;
	private static int KLABEL_REFRESH_INTERVAL = 10;
	private static int KLABEL_REFRESH_START_INTERVAL = 1000;
	
	private Thread iMainThread = null;
	
	private TextPaint iPaint = null;
	private RectF iRect = new RectF();
	private Rect iLabelRect = new Rect();
	private FontMetrics iFontMetrics = null;
	private float iFontHeight = 0;
	private float iBaseLine = 0;
	
	private String iLabel = null;
	private boolean iLongLabel = false;
	private String iCacheLabel = null;
	private RectF iCacheRect = null;
	private Rect iLabelBounds = new Rect();
	
	public MarqueeLabel(Context context) {
		this(context, null);
	}
	
	public MarqueeLabel(Context context, AttributeSet attrs) {
		super(context, attrs);
		iMainThread = Thread.currentThread();
		
		if ((iPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG)) != null){
			if (KMARQUEE_STEP_WIDTH == 0){
				KMARQUEE_STEP_WIDTH = iPaint.getTextScaleX();
			}
			
			if (KDEFAULT_LABEL_SIZE == 0){
				TextView tText = new TextView(this.getContext());
				
				KDEFAULT_LABEL_SIZE = tText.getTextSize();
			}
			
			iPaint.setTextSize(KDEFAULT_LABEL_SIZE);
			
			iFontMetrics = iPaint.getFontMetrics();
			
			iFontHeight = (float) (Math.ceil(iFontMetrics.descent - iFontMetrics.ascent) + 2);
		}
		
		this.setBackgroundColor(Color.TRANSPARENT);
	}

	private boolean iRtoL = true;
	private Handler iHandler = new Handler(){
		@Override
		public void handleMessage(Message msg) {
			if (msg != null){
				if (msg.what == KMESSAGE_REFRESH_LABEL){
					if (MarqueeLabel.this.isShown() && iLabel != null && iLabel.length() > 0 && iLabelRect != null && iLabelBounds != null){
						boolean tStart = false;
						
						if (iLongLabel){
							if(iLabelRect.left > -(iLabelBounds.width() - iCacheRect.left)){
								iLabelRect.left -= KMARQUEE_STEP_WIDTH;
							}else{
								tStart = true;
								
								iLabelRect.left = (int) iCacheRect.left;
							}
						}else{
							if (iRtoL){
								if (iLabelRect.left >= -(iLabelBounds.width() - iCacheRect.left - iCacheRect.width())){
									iLabelRect.left -= KMARQUEE_STEP_WIDTH;
								}else{
									tStart = true;
									
									iRtoL = false;
								}
							}else{
								if (iLabelRect.left <= iCacheRect.left){
									iLabelRect.left += KMARQUEE_STEP_WIDTH;
								}else{
									tStart = true;
									
									iRtoL = true;
								}
							}
						}
						
						invalidate();
						
						if (iHandler.hasMessages(KMESSAGE_REFRESH_LABEL) == false){
							iHandler.sendEmptyMessageDelayed(KMESSAGE_REFRESH_LABEL, tStart ? KLABEL_REFRESH_START_INTERVAL : KLABEL_REFRESH_INTERVAL);
						}
					}
				}
			}
		}
	};
	
	private void startMarquee(){
		if (iHandler != null){
			if (iHandler.hasMessages(KMESSAGE_REFRESH_LABEL) == false){
				iHandler.sendEmptyMessageDelayed(KMESSAGE_REFRESH_LABEL, KLABEL_REFRESH_START_INTERVAL);
			}
		}
	}
	
	@Override
	public void postInvalidate() {
		if (Thread.currentThread() == iMainThread){
			super.invalidate();
		}else{
			super.postInvalidate();
		}
	}
	
	private void refreshLabel(){
		if (iHandler.hasMessages(KMESSAGE_REFRESH_LABEL)){
			iHandler.removeMessages(KMESSAGE_REFRESH_LABEL);
		}
		
		if (iLabel != null){
			int tFrameWidth = iLabelRect.width();
			int tLabelWidth;
			
			iLabelRect.left = 0;
			
			iPaint.getTextBounds(iLabel, 0, iLabel.length(), iLabelBounds);
			
			tLabelWidth = iLabelBounds.width();
			
			if (tLabelWidth > tFrameWidth){
				iLongLabel = (tLabelWidth - tFrameWidth > (tFrameWidth >> 1));
				
				if (iLongLabel){
					iCacheLabel = iLabel + "      " + iLabel;
					
					iPaint.getTextBounds(iCacheLabel, 0, iCacheLabel.length(), iLabelBounds);
					
					iLabelBounds.right -= tLabelWidth;
				}else{
					iRtoL = true;
					
					iCacheLabel = iLabel;
				}
				
				iCacheRect = new RectF(iLabelRect.height() >> 2, 0, iLabelRect.width(), iLabelRect.height());
				iCacheRect.right -= iCacheRect.left;
				
				iLabelRect.left = (int) iCacheRect.left;
				
				startMarquee();
			}else{
				iCacheRect = null;
				
				iCacheLabel = iLabel;
				
				iLabelRect.left = (iLabelRect.width() - iLabelBounds.width()) >> 1;
			}
		}else{
			iCacheLabel = null;
		}
		
		postInvalidate();
	}
	
	public void setText(String aLabel){
		if (aLabel != null){
			if (aLabel.equals(iLabel) == false){
				iLabel = aLabel;
			}else{
				return;
			}
		}else{
			if (iLabel != null){
				iLabel = null;
			}else{
				return;
			}
		}
		
		refreshLabel();
	}
	
	public int getFontHeight(){
		return (int) iFontHeight;
	}

	private int mTextColor = Color.WHITE;
	public void setTextColor(int color){
		mTextColor = color;
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		
		if (iCacheLabel != null && iPaint != null){
			int tPadding = (int)iRect.height() >> 1;
			final RectF tClip = iCacheRect;
//			iPaint.setColor(Color.LTGRAY);
//			iPaint.setColor(mTextColor);
//			canvas.drawRoundRect(iRect, tPadding, tPadding, iPaint);
			
			iPaint.setColor(mTextColor);
			
			if (tClip != null){
				canvas.clipRect(tClip);
			}
			
			canvas.drawText(iCacheLabel, iLabelRect.left, iBaseLine, iPaint);
		}
	}
	
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		
		iRect.set(0, 0, w, h);
		iLabelRect.set(0, 0, w, h);
		iBaseLine = iLabelRect.top + (iLabelRect.bottom - iLabelRect.top - iFontMetrics.bottom + iFontMetrics.top) / 2 - iFontMetrics.top;
		
		refreshLabel();
	}
	
	
}
